<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import gsap from 'gsap'
import Draggable from 'gsap/Draggable'
import {
  minWindowWidth,
  minWindowHeight,
  type BaseWindow,
} from './class/basewindow'
import type { WindowControlArea } from './class/windowcontrolarea'
import { getWindowByPoint } from './ts/windowmanager'
import { cursorSize } from '../canvas/cursor/cursor'
import { windowSeparatorLineWidth } from './class/windowseparatorline'

const props = defineProps<{
  /** 拖动区域数据 */
  data: WindowControlArea
  /** 光标形状url */
  cursorUrl: string
}>()

const style = computed(() => {
  const win = props.data.window
  const top = win.top as number
  const left = win.left as number
  const right = win.right as number
  const o = {
    cursor: props.cursorUrl
      ? `url(${props.cursorUrl}) ${cursorSize / 2} ${cursorSize / 2}, auto`
      : 'crosshair',
    top: `${top + 1}px`,
    left: '',
    right: '',
  }
  if (props.data.align === 'left') {
    // 如果是在左侧
    o.left = `${left + 1}px`
  } else {
    // 如果是在右侧
    o.left = `${right - 20}px`
  }
  return o
})

const emit = defineEmits<{
  (
    e: 'onAddWindow',
    data: WindowControlArea,
    direction: 'bottom' | 'left' | 'right',
    startXY: number
  ): void
  (e: 'onDrag', line: WindowControlArea, offsetX: number, offsetY: number): void
  (e: 'onShowMergeBox', win: BaseWindow, targetWin: BaseWindow): void
  (e: 'onHideMergeBox'): void
  (e: 'onReleaseControlArea'): void
}>()

let state = 0 // 状态：0初始1新建拖动2可合并
let targetWin: BaseWindow // 合并窗口
let direction: 'bottom' | 'left' | 'right' = 'bottom' // 朝向

const $area = ref()
onMounted(() => {
  /** 拖动区域所在窗口 */
  const win = props.data.window
  const rect = win.rect as DOMRect
  const top = win.top as number
  const bottom = win.bottom as number
  const height = bottom - top
  const left = win.left as number
  const right = win.right as number
  const width = right - left
  Draggable.create($area.value, {
    cursor: style.value.cursor,
    activeCursor: style.value.cursor,
    type: 'x,y',
    inertia: true,
    liveSnap: true,
    onDrag: function (event: PointerEvent) {
      /** 容器中的x位置 */
      const relativeX = event.clientX - rect.left
      /** 容器中的y位置 */
      const relativeY = event.clientY - rect.top
      /** 当前光标所在窗口 */
      const currWin = getWindowByPoint(relativeX, relativeY)
      if (state === 0) {
        // 如果是初始状态
        const offsetY = relativeY - top
        if (
          currWin === win &&
          offsetY >= minWindowHeight &&
          height >= minWindowHeight * 2 + windowSeparatorLineWidth
        ) {
          // 如果 目标窗口是当前窗口 | 向下拖动足够大 | 空间足够
          state = 1
          direction = 'bottom'
          emit('onAddWindow', props.data, direction, top + minWindowHeight)
          return
        }
        if (props.data.align === 'left') {
          // 如果是左侧的控制区域
          const offsetX = relativeX - left
          if (offsetY < -windowSeparatorLineWidth) {
            // 如果是向上拖动
            if (currWin) {
              // 如果找到窗口
              // todo 判断能否合并
              if (win.parent !== undefined && win.parent === currWin.parent) {
                // 如果两个窗口是在同一个布局下
                if (
                  top <
                  (currWin.bottom as number) + windowSeparatorLineWidth * 2
                ) {
                  // 如果是挨着的窗口（避免跨窗口的情况出现，因为有可能光标移动过快）
                  state = 2
                  targetWin = currWin
                  return
                }
              } else {
                // 如果两个窗口不在同一个布局下
                if (
                  top <
                  (currWin.bottom as number) + windowSeparatorLineWidth * 2
                ) {
                  // 如果是挨着的窗口（避免跨窗口的情况出现，因为有可能光标移动过快）
                  // 如果上面的窗口的左边线与下面的窗口的左边线过近
                }
              }
            }
            return
          } else if (offsetX < -windowSeparatorLineWidth) {
            // 如果是向左拖动
            if (currWin) {
              // 如果找到窗口
              // todo 判断能否合并
              if (win.parent !== undefined && win.parent === currWin.parent) {
                // 如果两个窗口是在同一个布局下
                if (
                  left <
                  (currWin.right as number) + windowSeparatorLineWidth * 2
                ) {
                  // 如果是挨着的窗口（避免跨窗口的情况出现，因为有可能光标移动过快）
                  state = 2
                  targetWin = currWin
                  return
                }
              }
            }
          }
          if (
            currWin === win &&
            offsetX >= minWindowWidth &&
            width >= minWindowWidth * 2 + windowSeparatorLineWidth
          ) {
            // 如果 目标窗口是当前窗口 | 向右拖动足够大 且 空间足够
            state = 1
            direction = 'right'
            emit('onAddWindow', props.data, direction, left + minWindowWidth)
            return
          }
        } else {
          // 如果是右侧的控制区域
          const offsetX = relativeX - right
          if (offsetY < -windowSeparatorLineWidth) {
            // 如果是向上拖动
            if (currWin) {
              // 如果找到窗口
              // todo 判断能否合并
              if (win.parent !== undefined && win.parent === currWin.parent) {
                // 如果两个窗口是在同一个布局下
                if (
                  top <
                  (currWin.bottom as number) + windowSeparatorLineWidth * 2
                ) {
                  // 如果是挨着的窗口（避免跨窗口的情况出现，因为有可能光标移动过快）
                  state = 2
                  targetWin = currWin
                  return
                }
              }
            }
            return
          } else if (offsetX > windowSeparatorLineWidth) {
            // 如果是向右拖动
            if (currWin) {
              // 如果找到窗口
              // todo 判断能否合并
              if (win.parent !== undefined && win.parent === currWin.parent) {
                // 如果两个窗口是在同一个布局下
                if (
                  right >
                  (currWin.left as number) - windowSeparatorLineWidth * 2
                ) {
                  // 如果是挨着的窗口（避免跨窗口的情况出现，因为有可能光标移动过快）
                  state = 2
                  targetWin = currWin
                  return
                }
              }
            }
          }
          if (
            currWin === win &&
            offsetX <= -minWindowWidth &&
            width >= minWindowWidth * 2
          ) {
            // 如果 目标窗口是当前窗口 | 向左拖动足够大 | 空间足够
            state = 1
            direction = 'left'
            emit(
              'onAddWindow',
              props.data,
              direction,
              right - minWindowWidth - windowSeparatorLineWidth
            )
            return
          }
        }
      } else if (state === 1) {
        // 如果是新建拖动状态
        const offsetY = relativeY - top
        let realOffsetX, realOffsetY
        const maxWidth = width - minWindowWidth * 2 - windowSeparatorLineWidth
        const maxHeight =
          height - minWindowHeight * 2 - windowSeparatorLineWidth
        if (direction === 'left') {
          // 如果是因向左拖动创建
          realOffsetY = 0
          const offsetX = relativeX - right
          realOffsetX = offsetX + minWindowWidth + windowSeparatorLineWidth / 2
          if (realOffsetX > 0) {
            // 如果超过右边界
            realOffsetX = 0
          } else if (realOffsetX < -maxWidth) {
            // 如果超过左边界
            realOffsetX = -maxWidth
          }
        } else if (direction === 'right') {
          // 如果是因向右拖动创建
          realOffsetY = 0
          const offsetX = relativeX - left
          realOffsetX = offsetX - minWindowWidth - windowSeparatorLineWidth / 2
          if (realOffsetX < 0) {
            // 如果超过左边界
            realOffsetX = 0
          } else if (realOffsetX > maxWidth) {
            // 如果超过右边界
            realOffsetX = maxWidth
          }
        } else {
          // 如果是因向下拖动创建
          realOffsetX = 0
          realOffsetY = offsetY - minWindowHeight - windowSeparatorLineWidth / 2
          if (realOffsetY < 0) {
            // 如果超过上边界
            realOffsetY = 0
          } else if (realOffsetY > maxHeight) {
            // 如果超过下边界
            realOffsetY = maxHeight
          }
        }
        emit('onDrag', props.data, realOffsetX, realOffsetY)
      } else if (state === 2) {
        // 如果是可合并状态
        if (currWin === targetWin) {
          // 如果当前窗口是目标窗口
          console.log('合并到目标窗口')
          emit('onShowMergeBox', win, targetWin)
        } else if (currWin === win) {
          // 如果当前窗口是原窗口
          console.log('合并到原窗口')
          emit('onShowMergeBox', targetWin, win)
        } else {
          // 如果在窗口的间隙中或在其他窗口中
          console.log('取消合并')
          emit('onHideMergeBox')
        }
      }
      // updateSeparator(line, x, y, top, bottom, left, right)
      // emit('onDrag', event)
      // console.log('onDrag', event)
    },
    onRelease: function () {
      emit('onReleaseControlArea')
      // console.log('onRelease', event)
      gsap.to($area.value, { x: 0, y: 0, duration: 0 })
    },
  })[0]
})
</script>

<template>
  <div ref="$area" class="window-control-area" :style="style"></div>
</template>

<style scoped lang="less">
.window-control-area {
  background-color: red;
  position: absolute;
  z-index: 2;
  // width: calc(var(--window-height) - 10px);
  // height: calc(var(--window-height) - 1px);
  width: 20px;
  height: 20px;
  margin: 0;
}
</style>
